home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_03_02
/
3n02018a
< prev
next >
Wrap
Text File
|
1991-12-14
|
17KB
|
541 lines
/* fader.c - main code for fader custom control */
#include <windows.h>
#include "fader.h"
#define NO_DRAG 0 /* Values of FADER_THUMBSTATE */
#define DRAG 1
#define FADER_THUMB_OFFSET 2 /* Distance in pixels from edge */
/* Window extra bytes */
#define FADER_RANGE 0 /* logical range values returned */
#define FADER_VALUE 4 /* Current logical value */
#define FADER_THUMBSTATE 6 /* DRAG or NO_DRAG */
#define FADER_WNDEXTRA 8 /* Total # of window extra bytes */
HANDLE hGlobFaderInstance = NULL;
char szGlobControlName[] = "Fader";
/* Forward declarations for completeness */
static BOOL NEAR PASCAL RegisterControlClass (HANDLE hInstance);
LONG FAR PASCAL FaderWndFn (HWND hWnd, WORD wMsg,
WORD wParam, LONG lParam);
int GetThumbHeight(int iTotalHeight);
void GetFaderThumbRect(HWND hWnd, LPRECT pRc, LPRECT pThumbRect,
int iCurPos);
int XlatPosPhysicalToLogical(LONG lLogRange, int iPhysMax,
int iPhysMin, int iCurPos);
int XlatPosLogicalToPhysical(LONG lLogRange, int iPhysMax,
int iPhysMin, int iLogPos);
static void DrawCaret(HDC hDC, LPRECT lprc);
static void PaintFader(HWND hWnd);
/* These are DLL initialization and control functions */
BOOL FAR PASCAL LibMain (HANDLE hModule, WORD wDataSeg,
WORD wHeapSize, LPSTR lpszCmdLine)
{
hGlobFaderInstance = hModule;
if (wHeapSize != 0) /* Moveable DS */
UnlockData(0);
return RegisterControlClass(hModule);
}
int FAR PASCAL WEP (int nSystemExit)
{
UnregisterClass(szGlobControlName, hGlobFaderInstance);
return 1; /* never fails */
}
/* This function can be static if you only plan to use it
in a DLL */
BOOL NEAR PASCAL RegisterControlClass (HANDLE hInstance)
{
WNDCLASS wc;
wc.style = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = FaderWndFn;
wc.cbClsExtra = 0;
wc.cbWndExtra = FADER_WNDEXTRA;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_SIZENS);
wc.hbrBackground = COLOR_WINDOW + 1;
wc.lpszMenuName = NULL;
wc.lpszClassName = szGlobControlName;
return RegisterClass(&wc);
}
/* This function is handy for sending the FDRN_... messages
back to the parent. Note that FDRN_THUMBTRACK is disabled
unless FDRS_TRACK is enabled */
static LONG NEAR PASCAL NotifyParent (HWND hWnd,
WORD wNotifyCode)
{
BOOL bSend=TRUE;
if (wNotifyCode == FDRN_THUMBTRACK)
bSend = (BOOL) (GetWindowLong(hWnd, GWL_STYLE) & FDRS_TRACK);
if (bSend)
return SendMessage(GetParent(hWnd), WM_COMMAND,
GetWindowWord(hWnd, GWW_ID),
MAKELONG(hWnd, wNotifyCode));
else
return 0;
}
/* This is the main "window function" procedure, it is called
sometimes by the SDK Dialog box editor */
LONG FAR PASCAL FaderWndFn (HWND hWnd, WORD wMsg,
WORD wParam, LONG lParam)
{
LONG lResult = 0;
HDC hDC;
POINT pt;
RECT rc;
int iLogPos;
int iOldLogPos;
int iPhyPos;
int iMaxLog;
int iMinLog;
RECT thumb_rect;
LONG lLogRange;
int iThumbHalf;
HANDLE hNewBrush, hOldBrush;
switch (wMsg) {
case WM_CREATE:
SendMessage(hWnd, FDRM_SETRANGE, 0, MAKELONG(0, 100));
SendMessage(hWnd, FDRM_SETLOGVALUE, 0, 0);
break;
case WM_GETDLGCODE: /* interface query by dialog manager */
lResult = DLGC_WANTARROWS;
break;
case WM_PAINT:
PaintFader(hWnd);
break;
case WM_SETFOCUS: /* receiving the keyboard focus */
case WM_KILLFOCUS: /* losing the keyboard focus */
/* calculate update region */
GetClientRect(hWnd, &rc);
iLogPos = GetWindowWord(hWnd, FADER_VALUE);
GetFaderThumbRect(hWnd, (LPRECT)&rc, (LPRECT)&thumb_rect,
iLogPos);
if (thumb_rect.left == rc.left)
break;
/* force a repaint */
hDC = GetDC( hWnd );
if (hDC) {
/* define appropriate brush & text colors */
if (hNewBrush = (HBRUSH)SendMessage( GetParent(hWnd),
WM_CTLCOLOR, hDC, MAKELONG(hWnd,CTLCOLOR_BTN) ) )
hOldBrush = SelectObject(hDC,hNewBrush);
else
hOldBrush = NULL;
/* draw caret */
DrawCaret(hDC, (LPRECT)&thumb_rect);
/* restore original brush */
if ( hNewBrush ) {
SelectObject( hDC, hOldBrush );
DeleteObject( hNewBrush );
}
/* release display context */
ReleaseDC( hWnd, hDC );
}
break;
case WM_KEYDOWN: /* process virtual key code */
GetClientRect(hWnd, &rc);
iLogPos = (int)GetWindowWord(hWnd, FADER_VALUE);
iOldLogPos = iLogPos;
lLogRange = GetWindowLong(hWnd, FADER_RANGE);
iMaxLog = HIWORD(lLogRange);
iMinLog = LOWORD(lLogRange);
switch (wParam) {
case VK_HOME : /* home key */
iLogPos = iMinLog;
break;
case VK_END : /* end key */
iLogPos = iMaxLog;
break;
case VK_LEFT : /* cursor left key */
case VK_DOWN : /* cursor down key */
if (iLogPos < iMaxLog)
iLogPos++;
break;
case VK_UP : /* cursor up key */
case VK_RIGHT : /* cursor right key */
if (iLogPos > iMinLog)
iLogPos--;
break;
case VK_PRIOR : /* page up key */
iLogPos -= (iMaxLog - iMinLog) / 8;
if (iLogPos < iMinLog)
iLogPos = iMinLog;
break;
case VK_NEXT : /* page down key */
iLogPos += (iMaxLog - iMinLog) / 8;
if (iLogPos > iMaxLog)
iLogPos = iMaxLog;
break;
default : /* something else */
break;
}
if (iLogPos != iOldLogPos) /* did it change? */
{
SendMessage(hWnd, FDRM_SETLOGVALUE, iLogPos, 0);
NotifyParent(hWnd, FDRN_THUMBTRACK);
/* Invalidate old position */
GetFaderThumbRect(hWnd, (LPRECT)&rc,
(LPRECT)&thumb_rect, iOldLogPos);
InvalidateRect(hWnd, (LPRECT)&thumb_rect, TRUE);
/* Invalidate new position */
GetFaderThumbRect(hWnd, (LPRECT)&rc,
(LPRECT)&thumb_rect, iLogPos);
InvalidateRect(hWnd, (LPRECT)&thumb_rect, TRUE);
}
break;
case WM_LBUTTONDOWN:
GetClientRect(hWnd, &rc);
iLogPos = GetWindowWord(hWnd, FADER_VALUE);
GetFaderThumbRect(hWnd, (LPRECT)&rc, (LPRECT)&thumb_rect, iLogPos);
pt = MAKEPOINT(lParam);
/* is the mouse in the "hot" rectangle? */
if ((thumb_rect.top <= pt.y) && (thumb_rect.bottom >= pt.y) &&
(thumb_rect.left <= pt.x) && (thumb_rect.right >= pt.x)) {
SetWindowWord(hWnd, FADER_THUMBSTATE, DRAG);
hDC = GetDC(hWnd);
InvertRect(hDC, (LPRECT)&thumb_rect);
ReleaseDC(hWnd, hDC);
NotifyParent(hWnd, FDRN_THUMBTRACK);
/* grab focus if necessary */
if ( GetFocus() != hWnd )
SetFocus( hWnd );
/* Lock mouse on to this window */
SetCapture(hWnd);
}
break;
case WM_MOUSEMOVE:
case WM_LBUTTONUP:
/* Nothing to do if not in drag! */
if ((wMsg == WM_MOUSEMOVE) &&
(GetWindowWord(hWnd, FADER_THUMBSTATE) != DRAG) ) {
lResult = DefWindowProc(hWnd, wMsg, wParam, lParam);
break;
}